<?php defined('SYSPATH') or die('No direct script access.');
//this is basic class for loading page/layout data/templates from json or csv files
//usually you have a Controller which grabs needed data from database using models, etc and passes it onto the view/template files
class View_Page {

    private $type;
    private $name;
    private $vars; //holds the variables and data that will be accessed in mustache via page.variableName or layout.variableName

    private $data_dir;
    private $views_dir;
    private $_basedir;

    private function _load_file($base_dir, $name, $extension = NULL) {
        $filename = Kohana::find_file($base_dir, $name, $extension);

        if (! $filename) {
            throw new Kohana_Exception('Mustache template ":name" not found', array(':name' => $name));
        }

        return file_get_contents($filename);
    }

    //$page = new Page( array('path' => $path, 'name' => $page_name, 'type' => 'page') )
    public function __construct(array $options = array())
    {
        $this->_basedir = isset($options['base']) ? $options['base'] : 'aceui';
        $this->type = isset($options['type']) ? $options['type'] : 'page'; //page or layout?
        $this->name = $options["name"]; //page or layout name

        $this->data_dir = $options['path']['data'];

        $data = $this->_load_file($options['base'], "{$this->data_dir}/{$this->type}s/{$this->name}", 'json');//file_get_contents($filename);
        $this->vars = json_decode($data , TRUE);

        if(isset($this->vars['alias'])) {
            $this->name = $this->vars['alias'];
            $data = $this->_load_file($options['base'],"{$this->data_dir}/{$this->type}s/{$this->name}",'json');
            $this->vars = array_merge(json_decode($data , TRUE) , $this->vars);
        }

        if($this->type != "layout" && !isset($this->vars["layout"]))//if no default layout for this page, then consider it to be "default"
            $this->vars["layout"] = "default";

        $this->views_dir = $options['path']['views'];
        if($this->type == 'page') {
            if(is_file(Kohana::find_file($this->_basedir, "{$this->views_dir}/assets/scripts/{$this->name}", 'js'))) {
                $this->vars['inline_scripts'] = $this->_load_file($options['base'],"{$this->views_dir}/assets/scripts/{$this->name}",'js');
            }
            if(is_file(Kohana::find_file($this->_basedir, "{$this->views_dir}/assets/styles/{$this->name}", 'css'))) {
                $this->vars['inline_styles'] = $this->_load_file($options['base'],"{$this->views_dir}/assets/styles/{$this->name}",'css');
            }
        }


        $this->map_script_names();

        //now load all data relating to this page
        $this->load_data($this->data_dir);
    }


    /**
    This functions loads the data related to each page or layout
    for a page we load all files in the related directory
    for a layout we check the "datas-sources" attribute of our layout_file.json and load them
    In your real world application you can load data only when it is needed according to each page inside controllers
     */
    private function load_data($data_dir) {

        $data_files = array();
        $format = "/([0-9a-z\\-_]+)\\.(json|csv)$/i";

        //see if there's a folder for partial data relating to this page or layout
        //if so iterate all json/csv files and load the data
        $partial_data_folder = APPPATH.'/'.$this->_basedir."/{$data_dir}/{$this->type}s/partials/{$this->name}";
        $stats = null;
        if(is_dir($partial_data_folder)) {
            $files = scandir($partial_data_folder);
            foreach($files as $name) {
                if($name == '.' OR $name == '..')continue;

                if (! preg_match($format, $name , $filename) ) continue;
                $data_files[$filename[1]] = "{$partial_data_folder}/{$name}";
            }
        }


        foreach($data_files as $var_name => $var_value) {
            $new_data = '';
            if(preg_match("/\.json$/i" , $data_files[$var_name])) {
                $new_data = json_decode(file_get_contents($data_files[$var_name]) , TRUE);
            } else if(preg_match("/\.csv$/i" , $data_files[$var_name])) {
                //load csv data into an array
                $new_data = View_CSV::to_array($data_files[$var_name]);
                foreach($new_data as &$data) if(isset($data['status'])) $data[$data['status']] = true;
            }

            $this->vars[str_replace('.' , '_', $var_name)] = $new_data;
            //here we replace '.' with '_' in variable names, so template compiler can recognize it as a variable not an object
            //for example change sidebar.navList to sidebar_navList , because sidebar is not an object
        }

        return true;
    }

    private function map_script_names() {
        $vars = &$this->vars;

        //in our page's data file, we save short script/style names, which we must map to original file names
        //this way we can easily only the script-mapping file and changes will be reflected
        $mappables = array("script" , "style");
        foreach($mappables as $which) {
            if(isset($vars[$which.'s'])) {//if we have $vars["scripts"] or $vars["styles"]
                $page_scripts = $vars[$which.'s'];
                $map_json = json_decode($this->_load_file($this->_basedir,"{$this->data_dir}/common/{$which}-mapping.json", "") , TRUE);

                $mapped_scripts = array();
                foreach($page_scripts as $i => $script) {
                    if(isset($map_json[$page_scripts[$i]])) {
                        if(is_string($map_json[$page_scripts[$i]])) $mapped_scripts[] = $map_json[$page_scripts[$i]];
                        else //if(is_object($map_json[$page_scripts[$i]])) //two or more scripts should be included for this to work, like dataTables, jQuery UI, etc ...
                        {
                            foreach($map_json[$page_scripts[$i]] as $script_item)
                                $mapped_scripts[] = $script_item;
                        }
                    }
                }
                $vars[$which.'s'] = $mapped_scripts;

                if(isset($vars['ie_'.$which.'s'])) {
                    $ie_scripts = $vars['ie_'.$which.'s'];//ie_scripts || ie_styles
                    $ie_mapped_scripts = array();
                    foreach($ie_scripts as $script)
                        if(isset($map_json[$script['name']]))
                            $ie_mapped_scripts[] = array("version" => $script['version'] , "file_name" => $map_json[$script['name']]);

                    $vars['ie_'.$which.'s'] = $ie_mapped_scripts;
                }
            }
        }
    }






    public function get_template() {
        return $this->_load_file($this->_basedir,"{$this->views_dir}/{$this->type}s/{$this->name}.mustache","");
    }
    public function get_vars() {
        return $this->vars;
    }
    public function &get_var($name) {
        if(!isset($this->vars[$name])) {
            $result = null;
            return $result;
        }
        return $this->vars[$name];
    }
    public function get_name() {
        return $this->name;
    }

}
